#include "matrix.h"
#include "interrupt.h"
#include "stm32f4xx.h"
#include "timer.h"
#include "device.h"
#include "thread.h"

/* systick interrupt id */
#define SYSTICK_INTR_ID 0xF

/* device descriptor of systick */
static mx_device_t dev_systick;

/* systick interrupt handle */
static void systick_intr_handler (mx_void_pt param)
{
    /* system soft timer */
    mx_timer_tick();
}

static mx_device_ops_t ops = { /* no operations */ };

static mx_device_data_t devdata = {
    .name = "systick",
    .drvname = ""
};

void device_systick_init ()
{
    /* get cpu freq */
    RCC_ClocksTypeDef RCC_ClockFreq;
    RCC_GetClocksFreq(&RCC_ClockFreq);
    /* register systick device to system */
    mx_device_mount(&dev_systick, &devdata, &ops);
    /* register systick interrupt handler to system */
    mx_interrupt_register("systick-int15", SYSTICK_INTR_ID, systick_intr_handler, mx_null);
    /* systick NVIC configuratioin */
    NVIC_SetPriority(PendSV_IRQn, NVIC_EncodePriority(NVIC_PriorityGroup_0, 0, 1));     // can't be 0, 0 is for PendSV
    /* configure and start the systick of cortex-me, 1ms */
    SysTick_Config(RCC_ClockFreq.SYSCLK_Frequency / 1000);
}
MX_BOARDINIT_EXPORT(device_systick_init, 1);
